"""
Constants used in the Telnet protocol.

See http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/head/arpa/telnet.h
and http://www.faqs.org/rfcs/rfc854.html
"""

def invert_dict(d):
    result = {}
    for key, value in d.iteritems():
        result[value] = key
    return result
         
COMMAND = {
    'IAC': chr(255), # interpret as command:
    'DONT': chr(254), # you are not to use option
    'DO': chr(253), # please, you use option 
    'WONT': chr(252), # I won't use option
    'WILL': chr(251), # I will use option 
    'SB': chr(250), # interpret as subnegotiation
    'GA': chr(249), # you may reverse the line
    'EL': chr(248), # erase the current line
    'EC': chr(247), # erase the current character
    'AYT': chr(246), # are you there
    'AO': chr(245), # abort output--but let prog finish
    'IP': chr(244), # interrupt process--permanently
    'BREAK': chr(243), # break
    'DM': chr(242), # data mark--for connect. cleaning
    'NOP': chr(241), # nop
    'SE': chr(240), # end sub negotiation
    'EOR': chr(239), # end of record (transparent mode)
    'ABORT': chr(238), # abort process
    'SUSP': chr(237), # suspend process
    'EOF': chr(236), # end of file
}    
COMMAND_TO_STRING = invert_dict(COMMAND)

# this one is so common it gets its own constant
IAC = COMMAND['IAC']
OPERATIONS = frozenset(v for k,v in COMMAND.iteritems()
                        if k in ['WILL', 'WONT', 'DO', 'DONT'])

OPTION = {
    'BINARY': chr(0), # 8-bit data path
    'ECHO': chr(1), # echo
    'RCP': chr(2), # prepare to reconnect
    'SGA': chr(3), # suppress go ahead
    'NAMS': chr(4), # approximate message size
    'STATUS': chr(5), # give status
    'TM': chr(6), # timing mark
    'RCTE': chr(7), # remote controlled transmission and echo
    'NAOL ': chr(8), # negotiate about output line width
    'NAOP ': chr(9), # negotiate about output page size
    'NAOCRD': chr(10), # negotiate about CR disposition
    'NAOHTS': chr(11), # negotiate about horizontal tabstops
    'NAOHTD': chr(12), # negotiate about horizontal tab disposition
    'NAOFFD': chr(13), # negotiate about formfeed disposition
    'NAOVTS': chr(14), # negotiate about vertical tab stops
    'NAOVTD': chr(15), # negotiate about vertical tab disposition
    'NAOLFD': chr(16), # negotiate about output LF disposition
    'XASCII': chr(17), # extended ascic character set
    'LOGOUT': chr(18), # force logout
    'BM': chr(19), # byte macro
    'DET': chr(20), # data entry terminal
    'SUPDUP': chr(21), # supdup protocol
    'SUPDUPOUTPUT': chr(22), # supdup output
    'SNDLOC': chr(23), # send location
    'TTYPE': chr(24), # terminal type
    'EOR': chr(25), # end or record
    'TUID': chr(26), # TACACS user identification
    'OUTMRK': chr(27), # output marking
    'TTYLOC': chr(28), # terminal location number
    '3270REGIME': chr(29), # 3270 regime
    'X3PAD': chr(30), # X.3 PAD
    'NAWS': chr(31), # window size
    'TSPEED': chr(32), # terminal speed
    'LFLOW': chr(33), # remote flow control
    'LINEMODE': chr(34), # Linemode option
    'XDISPLOC': chr(35), # X Display Location
    'OLD_ENVIRON': chr(36), # Old - Environment variables
    'AUTHENTICATION': chr(37), # Authenticate
    'ENCRYPT': chr(38), # Encryption option
    'NEW_ENVIRON': chr(39), # New - Environment variables
    'EXOPL': chr(255), # extended-options-list
}    
OPTION_TO_STRING = invert_dict(OPTION)

SUBOPTION_QUALIFIER = {
    'IS': chr(0), # option is...
    'SEND': chr(1), # send option
    'INFO': chr(2), # ENVIRON: informational version of IS
    'REPLY': chr(2), # AUTHENTICATION: client version of IS
    'NAME': chr(3), # AUTHENTICATION: client version of IS
}
SUBOPTION_QUALIFIER_TO_STRING = invert_dict(SUBOPTION_QUALIFIER)  